<template>
  <div class="result-content">
    <div class="result-top out">
      <div class="in">
        <div class="resule-left">
        <div class="result-icon">
          <Icon icon="ep:checked" :size="44" color="#fff" />
        </div>
        <div v-if="!evaluateInfo.taskType" class="single-model-score">
          <span class="result-text">模型综合得分</span>
          <span class="result-score" >{{ singleModelScoreData[currentDataset] }}</span>
        </div>
        <div v-else  class="model-score">
          <span v-for="(item, i) in multiModelScoreData[currentDataset]" :key="i" class="single-model-score">
            <span class="result-text2">{{ item.name }}综合得分</span>
            <span class="result-score" >{{ item.value }}</span>
          </span>
        </div>
      </div>
      <div class="btn-group">
        <el-button plain type="primary" @click="handleExport">导出结果</el-button>
        <el-button type="primary" @click="handleScore">生成总分</el-button>
        <!-- <el-button type="warning" @click="handleReport">生成测评报告</el-button> -->
      </div>
      </div>
    </div>
  
    <!-- 模型评价结果 -->
    <el-card shadow="never" class="mt-16px" v-if="showEvaluateCard">
      <div class="dataset-top w-full mb-20px">
        <div class="dataset-title title-before">模型评价结果</div>
        <div class="flex">
          <span class="mr-16px lh-32px">选择分类:</span>
          <el-select v-model="currentDataset" @change="changeDataset" style="width: 260px">
            <el-option v-for="(d, i) in datasetList" :key="i" :value="d" :label="d" />
          </el-select>
        </div>
      </div>
      <el-row :gutter="40" justify="space-between">
          <el-col :xl="!evaluateInfo.taskType ? 12 : 18" :lg="!evaluateInfo.taskType ? 12 : 18" :md="!evaluateInfo.taskType ? 12 : 18" :sm="24" :xs="24">
            <el-skeleton :loading="evaluateLoading" animated :rows="6">
              <Echart v-if="!evaluateInfo.taskType" :options="pieOptionsData" :height="260" />
              <Echart v-else :options="lineOptionsData" :height="260" />
            </el-skeleton>
          </el-col>
          <el-col :xl="!evaluateInfo.taskType ? 12 : 6" :lg="!evaluateInfo.taskType ? 12 : 6" :md="!evaluateInfo.taskType ? 12 : 6" :sm="24" :xs="24" class="card-border">
            <el-skeleton :loading="evaluateLoading" animated :rows="6">
              <Echart :options="radarOptionsData" :height="260" />
            </el-skeleton>
          </el-col>
        </el-row>
    </el-card> 

    <!-- 列表 -->
    <ContentWrap class="mt-16px">
      <el-table
        :border="true"
        :data="tableData"
        :show-overflow-tooltip="true"
        :span-method="arraySpanMethod"
        :max-height="tableMaxHeight > 480 ? tableMaxHeight + 'px' : '480px'"
        style="min-height:470px"
        :header-cell-style="{ 'background': '#CCEBE7', 'text-align':'center', 'color': '#585858' }"
        class="details-table"
        >
        <el-table-column label="序号" type="index" width="60px" align="center" fixed="left" />
        <el-table-column label="测试集" align="center" min-width="100px" prop="datasetName" fixed="left" />
        <el-table-column label="prompt模板" align="center" min-width="180px" prop="promptName" fixed="left" />
        <el-table-column label="问题" align="center" min-width="200px" prop="datasetItemQuestion" fixed="left" />
        <el-table-column label="模型名称" align="center" min-width="120px" prop="largeModelName" fixed="left" />
        <el-table-column label="模型回答" align="center" min-width="100px" prop="modelAnswer" fixed="left" />
        <el-table-column label="答案" align="center" min-width="80px" prop="datasetItemAnswer" fixed="left" />
        <el-table-column label="状态" align="center" prop="status" width="100px" fixed="left">
              <template #default="scope">
                <div :class="['color-status-' + scope.row.status]" >
                  <span class="status-icon"></span>
                  <span>{{ taskStatus[scope.row.status] }}</span>
                </div>
              </template>
            </el-table-column>
        <el-table-column label="准确率" align="center" prop="indicator8Score"  min-width="110px" />
        <el-table-column label="rouge_1" align="center" prop="indicator1Score"  min-width="110px" />
        <el-table-column label="rouge_2" align="center" prop="indicator2Score"  min-width="110px" />
        <el-table-column label="rouge_l" align="center" prop="indicator3Score"  min-width="110px" />
        <el-table-column label="bleu_1_gram" align="center" min-width="120px" prop="indicator4Score" />
        <el-table-column label="bleu_2_gram" align="center" min-width="120px" prop="indicator5Score" />
        <el-table-column label="bleu_3_gram" align="center" min-width="120px" prop="indicator6Score" />
        <el-table-column label="bleu_4_gram" align="center" min-width="120px" prop="indicator7Score" />
        <el-table-column label="f1分数" align="center" prop="indicator9Score"  min-width="110px" />
        <el-table-column label="综合得分" align="center" prop="score"  min-width="110px" />
        <el-table-column label="操作" align="center" fixed="right" width="120px" >
          <template #default="scope">
            <el-button
              link
              :type="[3,6].includes(scope.row.status) ? 'danger' : ''"
              @click="openIssues(scope.row.id)"
              :disabled="![3,6].includes(scope.row.status)"
            >
              查看问题原因
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <!-- 分页 -->
      <Pagination
        :total="total"
        v-model:page="queryParams.pageNo"
        v-model:limit="queryParams.pageSize"
        @pagination="getTableData"
      />
    </ContentWrap>
  </div>
  
  <!-- 弹窗: 查看问题原因 -->
  <ViewIssues ref="issuesRef" />
  <!-- 弹窗：自定义指标评分权重 -->
  <EditScore ref="scoreRef" @success="indicatorWeightChange" />
</template>
<script setup lang="ts">
import { set } from 'lodash-es'
import { EChartsOption } from 'echarts'
import { EvaluationTaskApi } from '@/api/multiModel/evaluationtask'
import { pieOptions, radarOptions, lineOptions  } from './echarts-data'
import { PREDEFINE_COLORS, ECHARTS_COLORS, ECHARTS_COLORS2, hexToRGB } from '@/utils/color'
import download from '@/utils/download'
import { EvaluationTaskItemApi, EvaluationTaskItemVO } from '@/api/multiModel/evaluationtaskitem'
import ViewIssues from './viewIssues.vue'
import EditScore from './editScore.vue'
import type { TableColumnCtx } from 'element-plus'
import { dataMethod } from '@/utils/tableSpanMethod'

/** 评测任务 表单 */
defineOptions({ name: 'EvaluationTaskDetails' })

const message = useMessage() // 消息弹窗
const exportLoading = ref(false) // 导出的加载中

const tableData = ref<EvaluationTaskItemVO[]>([]) // 列表的数据
const total = ref(0) // 列表的总页数
const queryParams = reactive({
  pageNo: 1,
  pageSize: 10,
  evaluationTaskId: 0,
  largeModelId: undefined,
  datasetId: undefined,
  promptId: undefined,
  datasetItemId: undefined,
})
const route = useRoute()
const evaluationTaskId = ref()
let evaluationTaskInfo:any = reactive({})
const taskStatus:object = {
  0: '待推理',
  1: '推理中',
  2: '推理完成',
  3: '推理失败',
  4:  '评分中',
  5: '评分完成',
  6: '评分失败',
  7: '推理终止',
  8: '评分终止'
}
/** 导出按钮操作 */
const handleExport = async () => {
  try {
    // 导出的二次确认
    await message.exportConfirm()
    // 发起导出
    exportLoading.value = true
    const data = await EvaluationTaskItemApi.exportEvaluationTaskItem(queryParams)
    download.excel(data, '评测任务明细.xls')
  } catch {
  } finally {
    exportLoading.value = false
  }
}
const handleReport = () => {}
// 自定义评分权重弹窗
const scoreRef = ref()
const handleScore = async () => {
  await getEvaluationTaskInfo()
  scoreRef.value.open(evaluationTaskInfo)
}

/** 查询列表 */
let spanObj:object = {}
const getTableData = async () => {
  try {
    const data = await EvaluationTaskItemApi.getEvaluationTaskItemPage(queryParams)
    spanObj = dataMethod(data.list, ['datasetName', 'promptName', 'datasetItemQuestion'])
    tableData.value = data.list
    total.value = data.total
  } catch(e:any) {

  }
}

const getEvaluationTaskInfo = async () => {
  try {
    evaluationTaskInfo = await EvaluationTaskApi.getEvaluationTaskInfo(evaluationTaskId.value)
  } catch(e:any) {
  }
}

const issuesRef = ref()
const openIssues = async (id: number) => {
  const res = await EvaluationTaskItemApi.getErrorInfo( id)
  issuesRef.value.open(res)
}

const indicatorWeightChange = () => {
  getTableData()
  getEvaluationTaskInfo()
}

// 测评 统计
interface EvaluationTaskInfo {
  taskId:number;
  taskName:string;
  taskType:number;
  modelName:string;
  createTime:string
}
const evaluateInfo = ref<EvaluationTaskInfo>({
  taskId: 0,
  taskName: '',
  taskType: 0,
  modelName: ''	,
  createTime: ''
})
const evaluateLoading = ref(true)
const datasetList:string[] = reactive([])
const currentDataset = ref('')
const showEvaluateCard:boolean = ref(false)
const singleModelScoreData:any = ref({})
const multiModelScoreData:any = ref({})
let evaluateChartData:any = reactive({
  pieChart: null,
  lineChart: null,
  radarChart: null
})
const getEvaluateStat = async () => {
  initEvaluateChartData()
  const data = await EvaluationTaskApi.getEvaluateStat({taskId: evaluationTaskId.value})
  evaluateLoading.value = false
  if (data) {
    const { pieChart, lineChart, radarChart, singleModelScore, multiModelScore, ...params} = data
    evaluateInfo.value = params
    let convertRadarChart = {}
    radarChart.forEach(data => {
      for (let key in data) {
        datasetList.push(key)
        convertRadarChart[key] = data[key]
      }
    })
    evaluateChartData = {
      pieChart, 
      lineChart, 
      radarChart: convertRadarChart
    }
    if (datasetList.length) {
      currentDataset.value = datasetList[0]
    }
    showEvaluateCard.value = datasetList.length ? true : false
    singleModelScoreData.value = singleModelScore
    for (const key in multiModelScore) {
      let arr = []
      multiModelScore[key].forEach(model => {
        for (let k in model) {
          arr.push({
            name: k,
            value: model[k]
          })
        }
      })
      multiModelScoreData.value[key] = arr
    }
    changeDataset()
  }
}
const initEvaluateChartData = () => {
  evaluateChartData = {
    pieChart: null,
    lineChart: null,
    radarChart: null
  }
  datasetList.length = 0
  currentDataset.value = ''
}
const changeDataset = () => {
  if (evaluateInfo.value.taskType === 0 && evaluateChartData.pieChart) {
    getEvaluatePie(evaluateChartData.pieChart[currentDataset.value])
  }
  if (evaluateInfo.value.taskType === 1 && evaluateChartData.lineChart) {
    getEvaluateLine(evaluateChartData.lineChart)
  }
  if (evaluateChartData.radarChart) {
    getEvaluateRadar(evaluateChartData.radarChart[currentDataset.value])
  }
}
const pieOptionsData = reactive<EChartsOption>(pieOptions) as EChartsOption
// 单个评测--饼图
const getEvaluatePie = async (data) => {
  if (!data) return
  data.sort((a, b) => {
      return a.ydata - b.ydata
    })
  set(
    pieOptionsData,
    'legend.data',
    data.map((v) => v.xdata)
  )
  const seriesData = data.map((v) => {
    return {
      name: v.xdata,
      value: v.ydata
    }
  })
  set(pieOptionsData, 'series[0].data', seriesData)
  set(pieOptionsData, 'series[0].name', currentDataset.value)
}
const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
// 对比评测--折线图
const getEvaluateLine = async (datas) => {
  if (!datas) return
  let xdata:string[] = []
  let ydata:any = []
  for ( let key in datas) {
    xdata = datas[key].xdata
    ydata.push({
      name: key,
      value: datas[key].ydata
    })
  }
  set(
    lineOptionsData,
    'xAxis.data',
    xdata
  )
  let seriesData:any[] = []
  ydata.forEach((v, index) => {
    seriesData.push({
      name: v.name,
      type: 'line',
      stack: 'Total',
      showSymbol: false,
      data: v.value,
      areaStyle: {
        color: {
          type: 'linear',
          x: 0,
          y: 0,
          x2: 0,
          y2: 1,
          colorStops: [
            { offset: 0, color: hexToRGB(ECHARTS_COLORS[index], 0.4) },
            { offset: 1, color: hexToRGB(ECHARTS_COLORS[index], 0.2) }
          ],
          shadowColor: 'rgba(0, 0, 0, 0.1)',
          shadowBlur: 10
        }
      },
      itemStyle: {
        color: hexToRGB(ECHARTS_COLORS[index], 1),
        borderColor:hexToRGB(ECHARTS_COLORS[index], 0.01),
        borderWidth: 4
      }
    })
  })
  set(lineOptionsData, 'series', seriesData)
}
// 雷达图
const radarOptionsData = reactive<EChartsOption>(radarOptions) as EChartsOption
const getEvaluateRadar = async (data) => {
  if (!data) return
  const { xdata, ydata } = data
  set(
    radarOptionsData,
    'radar.indicator',
    xdata.map((v) => {
      return { name: v }
    })
  )
  set(radarOptionsData, 'series[0].data', [
    {
      value: ydata,
      name: currentDataset.value
    }
  ])
  if (!evaluateInfo.value.taskType) {
    set(
      radarOptionsData,
      'title',
      {
        text: '指标得分\n雷达图',
        show: true,
        left: 'left',
        top: 'center',
      }
    )
  }
}

// 合并单元格
interface SpanMethodProps {
  row: EvaluationTaskItemVO
  column: TableColumnCtx<EvaluationTaskItemVO>
  rowIndex: number
  columnIndex: number
}
const arraySpanMethod = ({row, column, rowIndex, columnIndex}: SpanMethodProps) => {
  let _row = spanObj[column.property] ? spanObj[column.property][rowIndex] : 1
  let _col = _row > 0 ? 1 : 0
  return {
    rowspan: _row,
    colspan: _col
  }
}

const tableMaxHeight = ref(300); // 初始高度
// 表格高度
const updateMaxHeight = () => {
  // 78 -16 - 56 - 86 - 16 - 486 - 50 - 110
  tableMaxHeight.value = document.body.clientHeight - 900; // 假设留出100px其他内容空间
}
window.addEventListener('resize', updateMaxHeight)
/** 初始化 **/
onMounted(async() => {
  evaluationTaskId.value = Number(route.query.id)
  queryParams.evaluationTaskId = Number(route.query.id)
  await Promise.all([getEvaluateStat(), getTableData()])
  updateMaxHeight()
})
onUnmounted(() => {
  window.removeEventListener('resize', updateMaxHeight)
})
</script>
<style lang="scss" scoped>
.result-top {
  &.out {
    border-radius: 5px;
    padding: 1px;
    background-image: linear-gradient(to right, #00BBB7 0%, #fff  100%);
  }
  .in {
    width: 100%;
    height: 100%;
    border-radius: 5px;
    background-image: linear-gradient(to right, #D2F2FD 0%, #fff  100%);
    display: flex;
    align-items: center;
    justify-content: space-between;
  }
  .resule-left {
    display: flex;
    align-items: center;
    // justify-content: space-between;
    justify-content: flex-start;
    flex: 1;
    padding: 10px 16px;
    .result-icon {
      width: 60px;
      height: 60px;
      margin-left: 40px;
      background: #00BBB8;
      border-radius: 8px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .result-text {
      font-size: 22px;
      font-weight: 700;
      margin-left: 20px;
      margin-right: 20px;
    }
    .result-text2 {
      font-size: 22px;
      font-weight: 600;
      margin-left: 12px;
      margin-right: 16px;
    }
    .result-score {
      font-size: 36px;
      font-weight: 700;
      color: #00BBB8
    }
  }
  .btn-group {
    padding: 10px 16px;
    // width: 200px;
  }
  
}
.echart-card-title {
  font-size: 18px;
  font-weight: 700;
  line-height: 22px;
  text-align: left;
  color: #333;
  position: relative;
  margin-bottom: 16px;
  &::before {
    position: absolute;
    z-index: 10;
    display: block;
    width: 4px;
    height: 24px;
    left: -16px;
    background-color: var(--el-color-primary);
    content: '';
  }
}
.dataset-top {
  display: flex;
  justify-content: space-between;
}
.dataset-title{
  font-size: 18px;
  color: #333;
  font-weight: 700;
}
.title-before {
  position: relative;
  &::before {
    position: absolute;
    top: 3px;
    left: -20px;
    display: inline-block;
    width: 4px;
    height: 20px;
    background-color: var(--el-color-primary);
    content: '';
  }
}
.echart-item {
  border-top: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  border-left: 1px solid #bbb;
  border-right: 1px solid #bbb;
  .echart-item-title {
    width: 20%;
    font-weight: 700;
    font-size: 16px;
    color: #333;
    text-align: center;
    padding-left: 5%
  }
  .echart-warp {
    width: 80%;
  }
}
.card-border {
  border-left: 1px solid #D9D9D9;
}
.details-table {
  :deep(.el-table__empty-block) {
    min-height: 430px
  }
}
 
.model-score {
  display:flex;
}
.single-model-score {
  display:flex;
  justify-content: center;
  align-items:center;
  margin-right: 20px;
}
</style>